package redis

import (
	"context"
	"gitee.com/brookscoder/awesome-mall-go/common/log"
	"github.com/go-redis/redis/v8"
	"go.uber.org/zap"
	"time"
)

var Rdb *redis.Client
var ctx = context.Background()

/*初始化Redis连接*/
func InitClient() bool {
	Rdb = redis.NewClient(&redis.Options{
		Addr:     "localhost:6379", //指定连接地址
		Password: "",               //无密码
		DB:       0,                //使用默认的数据库
		PoolSize: 100,              //连接池大小
	})

	// 超时参数
	_, cancel := context.WithTimeout(ctx, 5*time.Second)
	defer cancel()

	pong, err := Rdb.Ping(ctx).Result()
	if err != nil {
		log.Error(ctx, "初始化Redis服务失败", zap.Error(err))
		return false
	} else {
		log.Info(ctx, "初始化Redis服务成功", zap.Any("RediesPP", pong))
		return true
	}
}

// ----------- Public Method -----------
/*将验证码保存至缓存中*/
func WriteChptcha(phoneNum string, verifyCode string) bool {
	// 基于用户手机号组成缓存的Key
	key := "SMSCode" + phoneNum
	// 将随机生成的验证码，附加有效时长存入缓存中(NX:只有Key不存在时才生效，时间参数:默认为ns纳秒)
	err := Rdb.SetNX(ctx, key, verifyCode, 90*time.Second).Err()
	if err != nil {
		log.Error(ctx, "Redis保存验证码失败", zap.Error(err))
		return false
	} else {
		log.Info(ctx, "Redis保存验证码成功", zap.Any(key, verifyCode))
		return true
	}
}

/*从缓存中获取验证码&有效期*/
func ReadChptcha(phoneNum string) (verifyCode string, err error) {
	// 基于用户手机号组成缓存的Key
	key := "SMSCode" + phoneNum
	// 通过Key获取缓存的验证码 + 剩余时长
	val, err := Rdb.Get(ctx, key).Result()
	if err == redis.Nil {
		log.Warning(ctx, "Redis找不到这个验证码Key", zap.Error(err))
		return "", err
	} else if err != nil {
		log.Error(ctx, "Redis取验证码失败", zap.Error(err))
		return "", err
	} else {
		log.Info(ctx, "Redis取验证码成功", zap.Any("RedisName", val))
		return val, nil
	}
	return "", err
}

// -----------  Test Method  -----------
/*实验 Redis 基本读写操作*/
func TestRedis() {
	//testSetExampleValue()
	//testGetExampleValue()

	//WriteChptcha("10086", "123456")
	//ReadChptcha("10010")
	//ReadChptcha("10086")
}

func testSetExampleValue() {
	err := Rdb.Set(ctx, "RedisName", "Brooks", 0).Err()
	if err != nil {
		log.Error(ctx, "Redis存值失败", zap.Error(err))
	} else {
		log.Info(ctx, "Redis存值成功", zap.Skip())
	}
}

func testGetExampleValue() {
	val, err := Rdb.Get(ctx, "RedisName").Result()
	if err == redis.Nil {
		log.Warning(ctx, "Redis找不到这个Key", zap.Error(err))
	} else if err != nil {
		log.Error(ctx, "Redis取值失败", zap.Error(err))
	} else {
		log.Info(ctx, "Redis取值成功", zap.Any("RedisName", val))
	}
}
